#ifndef __FF_EXFUNS_H_
#define __FF_EXFUNS_H_

/* =========================== 用户配置 =========================== */

#include "main.h"
#include "System/DEBUG/debug.h"
#include "Middlewares/FATFS/ff.h"

#include "Middlewares/FREERTOS/include/FreeRTOS.h"
#include "Middlewares/FREERTOS/include/task.h"


#define FS_LOG(...) debug_printf(__VA_ARGS__) /* ff_exfuns_log日志输出 */

static inline void *FS_MALLOC(uint32_t size) /* 用户内存申请接口 */
{
    return pvPortMalloc(size);
}

static inline void FS_FREE(void *p) /* 用户内存释放接口 */
{
    vPortFree(p);
}



/* =========================== 外部声明 =========================== */

#include "stdint.h"

extern FATFS *fs[FF_VOLUMES]; /* 使用动态分配的文件系统对象指针,使用前需要初始化申请内存 */

/* ff_get_file_type 返回的类型定义*/
#define T_BIN       0X00    /* bin文件 */
#define T_LRC       0X10    /* lrc文件 */

#define T_NES       0X20    /* nes文件 */
#define T_SMS       0X21    /* sms文件 */

#define T_TEXT      0X30    /* .txt文件 */
#define T_C         0X31    /* .c文件 */
#define T_H         0X32    /* .h文件 */

#define T_WAV       0X40    /* WAV文件 */
#define T_MP3       0X41    /* MP3文件 */
#define T_FLAC      0X42    /* FLAC文件 */
#define T_APE       0X43    /* APE文件 */

#define T_BMP       0X50    /* bmp文件 */
#define T_JPG       0X51    /* jpg文件 */
#define T_JPEG      0X52    /* jpeg文件 */
#define T_GIF       0X53    /* gif文件 */

#define T_AVI       0X60    /* avi文件 */

/**
 * @brief    FATFS文件系统初始化
 * @param    无
 * @retval   0, 成功; 其他, 失败代码;
 */
uint8_t fs_init(void);

/**
 * @brief    FATFS文件系统反初始化
 * @param    无
 * @retval   无
 */
void fs_deinit(void);

/**
 * @brief    获取指定驱动器的总容量和剩余容量
 * @param    pdrv  : 物理驱动器号
 * @param    total : 总容量指针,单位KB
 * @param    free  : 剩余容量指针,单位KB
 * @retval   0, 成功; 其他, 失败代码;
 */
uint8_t fs_get_free(uint8_t pdrv, uint32_t *total, uint32_t *free);

/**
 * @brief    获取指定目录下的文件数量
 * @param    path  : 目录路径
 * @retval   文件数量
 */
uint8_t fs_get_file_num(uint8_t *path);

/**
 * @brief    获取指定目录下的文件名
 * @param    path  : 目录路径
 * @param    index : 文件索引
 * @param    name  : 文件名指针
 * @retval   0, 成功; 其他, 失败代码;
 * @note     index从1开始
 */
uint8_t fs_get_file_name(uint8_t *path, uint8_t index, char *name);

/**
 * @brief    判断指定路径是否为目录
 * @param    path  : 路径
 * @retval   0, 不是目录; 1, 是目录; 其他, 失败代码;
 */
uint8_t fs_is_folder(uint8_t *path);

/**
 * @brief    进入指定目录
 * @param    path  : 路径
 * @param    index : 目录索引
 * @retval   0, 成功; 其他, 失败代码;
 * @note     index从1开始
 */
uint8_t fs_enter_folder(uint8_t *path, uint8_t index);

/**
 * @brief    返回上一级目录
 * @param    path  : 路径
 * @retval   0, 成功; 其他, 失败代码;
 */
uint8_t fs_back_folder(uint8_t *path);

/**
 * @brief    获取指定文件在目录中的索引
 * @param    path  : 目录路径
 * @param    name  : 文件名
 * @retval   文件索引
 */
uint8_t fs_get_file_index(uint8_t *path, const uint8_t *name);

/**
 * @brief    从路径中获取文件名
 * @param    path  : 路径
 * @retval   文件名指针
 */
uint8_t *fs_get_src_name(uint8_t *path);

/**
 * @brief       报告文件的类型
 * @param       fname : 文件名
 * @retval      文件类型
 *   @arg       0XFF , 表示无法识别的文件类型编号.
 *   @arg       其他 , 高四位表示所属大类, 低四位表示所属小类.
 */
uint8_t fs_get_file_type(uint8_t *fname);

#endif
